<?php
/** 
 * 
 * Mysql connector based on PDB class
 *
 * @author Patrice Ferlet <metal3d@copix.org> 
 * @package db 
 * @license http://opensource.org/licenses/lgpl-3.0.html GNU Lesser General Public License Version 3.0 (LGPLv3)
*/

/**
 * PMySQL is the MySQL connector
 *
 * @author Patrice Ferlet <metal3d@copix.org> 
 */
class PMysqlDB extends PDB implements iPDB{
    //put your code here
    private $link;
    private $res = null;
    private $current = null;
    private $position = 0;

    /**
    * Connect to MySQL
    *
    * @param PStandardObject options (username, password, host, database)
    * @return this
    */
    public function connect(PStandardObject $options){
        $this->link =  mysql_connect($options->server, $options->username, $options->password);
        mysql_select_db($options->database, $this->link);

        return $this;
    }

    public function &getIndexes($tablename){
        if (count($this->indexes)) return $this->indexes;
        $res = $this->doQuery('show index from '.$tablename);
        $toReturn = array();
        foreach ($res as $row){
            $toReturn[]  = $row->Column_name;
        }
        $this->indexes = &$toReturn;
        return $this->indexes;
    }

    public function doQuery($query){
        $this->res = mysql_query($query, $this->link);
        //$this->position = 0;
        $this->rewind();
        return new PDBResult($this);
    }

    public function getFields($tablename) {
        $res = mysql_query('show fields from '.$tablename, $this->link);
        $toReturn = array();
        while ($row = mysql_fetch_object($res)){
            $toReturn[] = _obj(array(
                'name' => $row->Field,
                'type' => $row->Type,
                'key'  => ($row->Key) ? true : false,
                'primary' => ($row->Key == "PRI") ? true : false
            ));
        }
        return $toReturn;
    }


    public function getInsertID(){
        return mysql_insert_id($this->link);
    }
    
    public function insert(PDBRecord $record){
        $db = $record->getDB();
        $tab = $record->getTable();
        $sql = "INSERT INTO $tab ";

        $first = true;
        $values = "";
        foreach ($record->getFields() as $field){
             if ($field->primary) {
                $id = $field->name;
                continue; //we cannot insert key...
              }
             if(!$first) {
                $values .= ',';
                $fields .= ',';
             }
            $first = false;
            $fields .= $field->name;
            $values .= "'".$record->{$field->name}."'";      
        }
        $sql .= "($fields) values ($values)";
        $record->getDB()->doQuery($sql);
        $record->$id = $record->getDB()->getInsertID();
    }

    public function delete(PDBRecord $record){
        //we want to create SQL like 
        //delete from TABLE where key1=value1 and key2=value2...

        $sql = "delete from ".$record->getTable()." where ";
        $first = true;
        foreach ($record->getFields() as $field){
             if (!$field->primary) {
                continue; //we only need keys...
              }
             if(!$first) {
                $fields .= ' AND ';
             }
            $first = false;
            $sql .= $field->name."='".$record->{$field->name}."'";
        }

    }

    public function update(PDBRecord $record){
        //we want to create SQL like
        //update TABLE set field1='value', field2='value2'... where key1='keyval1' and key2='keyval2'
        $sql = "update ".$record->getTable()." set ";
        $first = true;
        $first_where = true;
        $where = " WHERE ";
        foreach ($record->getFields() as $field){
             if ($field->primary) {
                $id = $field->name;
                if(!$first_where) {
                   $where = ' AND ';
                }
                $first_where = false;
                $where = $field->name.'='.$record->${$field->name} ;
                continue; //we cannot change keys...
              }
             if(!$first) {
                $sql = ' , ';
             }
            $first = false;
            $sql = $field->name."='".$record->${$field->name}."'";
        }
        $sql .= $where;
    }

    /* Iterator */
    public function current () {
        return $this->current;
    }

    public function next () {
        if ($res = mysql_fetch_object($this->res)){
            $this->current = $res;
            $this->position ++;
            return $this->current;
        }
        $this->current=null;
        return false;
    }

    public function key () {
        return $this->position;
    }

    public function rewind(){
        $this->position=0;
        mysql_data_seek($this->res,0);
        $this->current = mysql_fetch_object($this->res);
    }
    public function valid(){
        return (bool) $this->current;
    }


   /* ArrayAccess */

    public function offsetExists($offset){
        if (mysql_data_seek($this->res, $offset)){
            //go back to current position
            mysql_data_seek($this->res, $this->position);
            return true;
        }
        return false;
    }

    public function offsetGet($offset){
        mysql_data_seek($this->res, $offset);
        $this->position = $offset;
        return mysql_fetch_object($this->res);
    }

    public function offsetUnset($offset){
        throw new PException("Error, you cannot unset value on resultsets");
    }

    public function offsetSet($offset, $val){
        throw new PException("Error, you cannot set value on resultsets");        
    }

}

